package ichubconfig

import (
	"gitee.com/ichub/webcli/common/base/baseconfig"
	"gitee.com/ichub/webcli/common/base/baseconsts"
	"gitee.com/ichub/webcli/common/base/basedto"
	"gitee.com/ichub/webcli/common/base/baseutils/fileutils"
	"gitee.com/ichub/webcli/common/ichublog"
	"github.com/jinzhu/copier"
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
	"os"
	"strings"
)

/*
	@Title    文件名称: ichub_config.go
	@Description  描述:  配置文件

	@Author  作者: leijianming@163.com  时间(2024-02-22 22:38:21)
	@Update  作者: leijianming@163.com  时间(2024-02-21 22:38:21)
*/

const ConfigfileIchubCommon = "/config/ichubcommon.yml"
const ConfigfileIchubengine = "/config/ichubengine.yml"
const ConfigfileIchubfactroy = "/config/factroy/ichubfactroy.yml"
const ConfigfileIchubdemo = "/config/ichubengine-demo.yml"

type Env string
type IchubConfig struct {
	basedto.BaseEntity
	Env string `json:"env"`

	BasePath   string `json:"base_path"`
	ConfigFile string `json:"config_file"`

	Etcd struct {
		Server struct {
			Hosturl string `json:"hosturl"`
		}
	}

	Rpc struct {
		ServerName string `json:"server_name"`
		ServerPort int    `json:"server_port"`
		ClientName string `json:"client_name"`
	}

	Web struct {
		Server struct {
			Name string `json:"name"`
			Port int    `json:"port"`
		}
		Client struct {
			Name    string `json:"name"`
			TestUrl string `json:"test_url"`
		}
		Swagger struct {
			Host     string `json:"host"`
			BasePath string `json:"base_path"`
			Version  string `json:"version"`
			Title    string `json:"title"`
			Enable   string `json:"enable"`
		}
	}

	Datasource struct {
		Dbtype string `json:"dbtype"`
		Dbname string `json:"dbname"`
		Host   string `json:"host"`
		Port   string `json:"port"`

		Username string `json:"username"`
		Password string `json:"password"`
		Sslmode  string `json:"sslmode"`
		Charset  string `json:"charset"`
	}

	Redis struct {
		Db       int    `json:"db"`
		Addr     string `json:"addr"`
		Password string `json:"password"`
	} `json:"redis"`

	Nats struct {
		Url string `json:"url"`
	}
	Es struct {
		Url      string `json:"url"`
		Username string `json:"username,omitempty"`
		Password string `json:"password,omitempty"`
	}
	Mysql struct {
		Dbtype string `json:"dbtype"`
		Dbname string `json:"dbname"`
		Host   string `json:"host"`
		Port   string `json:"port"`

		Username string `json:"username"`
		Password string `json:"password"`
		Sslmode  string `json:"sslmode"`
		Charset  string `json:"charset"`
	}
	Dbtype string `json:"dbtype"`
}

func New(configFile string) *IchubConfig {
	var cfg = &IchubConfig{
		Env:        baseconsts.ENV_EMPTY, // os.Getenv("env"),
		ConfigFile: configFile,
	}
	cfg.InitProxy(cfg)
	return cfg
}
func NewConfig() *IchubConfig {
	return New(ConfigfileIchubengine)
}

func NewCommon() *IchubConfig {

	return New(ConfigfileIchubCommon)
}

func (this *IchubConfig) Log() {
	ichublog.Log(this)
}

func (this *IchubConfig) ParseValues(key string, values ...*string) {

	for _, v := range values {
		item := baseconfig.NewConfigItem(key, *v)
		*v = item.ParseValue().EndValue
	}
	logrus.Info(values)
}
func (this *IchubConfig) ParseValue(key string, value string) string {

	item := baseconfig.NewConfigItem(key, value)
	var v = item.ParseValue().EndValue
	logrus.Info(v)
	return v
}

func (this *IchubConfig) FullFileName() string {
	this.Env = os.Getenv("env")
	var files = strings.Split(this.ConfigFile, ".")
	var env = "-" + this.Env
	if len(this.Env) == 0 {
		env = ""
	}
	var cfg = files[0] + env + "." + files[1]
	if len(this.BasePath) == 0 {
		this.BasePath = os.Getenv(baseconsts.IchubBasePath)
	}
	return this.BasePath + cfg
}

func (this *IchubConfig) LogFileName() {
	logrus.Info(this.FullFileName())
}

func (this *IchubConfig) CheckFileExist() bool {

	return fileutils.CheckFileExist(this.FullFileName())

}

func (this *IchubConfig) SetDefaultBasePath(basepath string) {
	if len(basepath) == 0 {
		basepath = os.Getenv(baseconsts.IchubBasePath)
	}
	if len(basepath) == 0 {
		basepath = fileutils.GetCurPath()
	}

	if this.ConfigFile == "" {
		this.ConfigFile = ConfigfileIchubengine
	}
	this.BasePath = basepath
}

func (this *IchubConfig) ReadConfig(basePath string) {
	this.SetDefaultBasePath(basePath)
	if !this.CheckFileExist() {
		panic("file not exist!" + this.FullFileName())
	}

	viper := viper.New()
	viper.SetConfigType("yaml")
	viper.SetConfigFile(this.FullFileName())

	err := viper.ReadInConfig()
	if err != nil {
		logrus.Error(err)
		return
	}
	err = viper.Unmarshal(this)
	if err != nil {
		logrus.Error(err)
	}
	logrus.Info("ReadConfig=", this)

}
func (this *IchubConfig) SetOsEnv(key, value string) *IchubConfig {
	os.Setenv(key, value)
	return this
}

func (this *IchubConfig) Read() *IchubConfig {
	var basepath = os.Getenv(baseconsts.IchubBasePath)
	if len(basepath) == 0 {
		basepath = fileutils.GetCurPath()
	}
	this.ReadConfig(basepath)
	this.Dbtype = this.ParseValue("dbtype", this.Dbtype)
	ichublog.Log(this.ToPrettyString())
	return this

}
func (this *IchubConfig) ReadIchubDb() *baseconfig.DbClientDto {

	this.Read()
	if this.Dbtype == baseconsts.DB_TYPE_MYSQL {
		return this.ReadIchubMysql()
	}
	if this.Dbtype == baseconsts.DB_TYPE_COCKROACH {
		return this.ReadIchubDatasource()
	}
	return this.ReadIchubDatasource()
}

func (this *IchubConfig) ReadIchubDatasource() *baseconfig.DbClientDto {

	this.Read()
	var dbClientDto = baseconfig.NewDbClientDto()
	copier.Copy(dbClientDto, &this.Datasource)

	return dbClientDto.Parse()
}

func (this *IchubConfig) ReadIchubMysql() *baseconfig.DbClientDto {

	this.Read()
	var dbClientDto = baseconfig.NewDbClientDto()
	copier.Copy(dbClientDto, &this.Mysql)

	return dbClientDto.Parse()
}

func (this *IchubConfig) ReadIchubRpc() *baseconfig.RpcServerDto {

	this.Read()
	var dto = &baseconfig.RpcServerDto{
		EtcdHost:   this.Etcd.Server.Hosturl,
		ServerName: this.Rpc.ServerName,
		ServerPort: this.Rpc.ServerPort,
		ClientName: this.Rpc.ClientName,
	}
	return dto.Parse()
}
func (this *IchubConfig) ReadIchubEs() *baseconfig.ElasticClientDto {

	this.Read()
	var dto = &baseconfig.ElasticClientDto{
		URL:      this.Es.Url,
		Username: this.Es.Username,
		Password: this.Es.Password,
	}
	return dto.Parse()
}
func (this *IchubConfig) ReadIchubRedis() *baseconfig.RedisClientDto {

	this.Read()
	var dto = &baseconfig.RedisClientDto{
		Addr:     this.Redis.Addr,
		Password: this.Redis.Password,
		DB:       this.Redis.Db,
	}
	return dto.Parse()
}
func (this *IchubConfig) ReadIchubWebServer() (serverDto *baseconfig.WebServerDto) {

	this.Read()
	serverDto = baseconfig.NewWebServerDto()

	serverDto.ServerName = this.Web.Server.Name
	serverDto.ServerPort = this.Web.Server.Port
	serverDto.EtcdHost = this.Etcd.Server.Hosturl
	return serverDto.Parse()
}

func (this *IchubConfig) ReadIchubWebClient() (clientDto *baseconfig.WebClientDto) {

	this.Read()
	clientDto = &baseconfig.WebClientDto{}
	clientDto.ServerName = this.Web.Client.Name
	clientDto.TestUrl = this.Web.Client.TestUrl
	clientDto.EtcdHost = this.Etcd.Server.Hosturl
	clientDto.Parse()

	return
}

func (this *IchubConfig) ReadIchubCommon() *IchubConfig {

	this.ConfigFile = ConfigfileIchubCommon
	this.Read()
	return this
}

/**
 * 读取配置文件,最先被初始化
 */
//func (this *IchubConfig) InitRoot() string {
//	return fileutils.FindRootDir()
//}

func (this *IchubConfig) ReadWebSwagger() *baseconfig.SwaggerClientDto {

	this.Read()
	var swagger = baseconfig.NewSwaggerClientDto()

	swagger.Host = this.Web.Swagger.Host
	swagger.BasePath = this.Web.Swagger.BasePath
	swagger.Version = this.Web.Swagger.Version
	swagger.Title = this.Web.Swagger.Title
	swagger.Enable = this.Web.Swagger.Enable

	return swagger.Parse()
}
